/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 2022 Huawei Technologies Co., Ltd */

#ifndef HIUDK3_H
#define HIUDK3_H
#ifdef HIUDK_SDK
#include<linux/pm.h>
#include<linux/mutex.h>
#include <linux/async.h>
#include "hiudk3_common.h"
#include "hiudk3_crm.h"
#include "hiudk3_cqm.h"
#include "hiudk3_hw.h"
#include "hiudk3_wq.h"
#include "hiudk3_hw.h"
#include "hiudk3_lld.h"

/* sdk 注册给UDK的全部API 接口函数 */
struct hiudk_ops {
    struct hiudk_crm_ops crm_ops;
    struct hiudk_com_ops com_ops;
    struct hiudk_cqm_ops cqm_ops;
    struct hiudk_hw_ops hw_ops;
    struct hiudk_wq_ops wq_ops;
    struct hiudk_dev_ops dev_ops;
};

#define UDK_MAX_SDK 2
#define UDK_MAX_SDK_NAME 21
#define UDK_MAX_PF_NUM 32

enum hiudk_sdk_state {
	SDK_NOT_IN_REMOVE = 0,
	SDK_IN_REMOVE,
};

#define CHECK_UDK_DEV(x) (((x) != NULL) && (((struct hiudk_dev *)(x))->magic == UDK_MAGIC_LONG))
#define GET_SDKHWDEV_FROM_HIUDKHWDEV(x) (((struct hiudk_dev *)(x))->hwdev)

typedef int (*hiudk_flush_fn)(void *priv_data);
typedef struct hiudk_dev_flush_infos {
    void *lld_dev;
    hiudk_flush_fn flush_ops;

    /* private: Internal use */
    int ret;
} hiudk_dev_flush_infos;

typedef struct hiudk_async_ctrl {
    spinlock_t lock;

    hiudk_dev_flush_infos flush_infos[UDK_MAX_PF_NUM];
} hiudk_async_ctrl;

int wait_for_devices_flush(struct notifier_block *nb, unsigned long action, void *data);
int hiudk_register_flush_fn(void *lld_dev, hiudk_flush_fn fn);
int hiudk_unregister_flush_fn(void *lld_dev);

struct hiudk_sdk {
    int (*hiudk_register_uld)(enum hinic3_service_type type, struct hinic3_uld_info *uld_info);
    void (*hiudk_unregister_uld)(enum hinic3_service_type type);
    struct hinic3_lld_dev *(*hiudk_get_lld_dev_by_dev_name)(const char *dev_name, enum hinic3_service_type type);
    struct hinic3_lld_dev *(*hiudk_get_lld_dev_by_dev_name_unsafe)(const char *dev_name, enum hinic3_service_type type);
    struct hinic3_lld_dev *(*hiudk_get_lld_dev_by_chip_and_port)(const char *chip_name, u8 port_id);
    void *(*hiudk_get_ppf_dev)(void);
    char sdk_lable[UDK_MAX_SDK_NAME];
    unsigned char idx;   /* sdk index */
};

int hiudk_register_sdk(struct hiudk_sdk *sdk);
int hiudk_unregister_sdk(unsigned idx);
void  *hiudk_get_dev_hdl_from_hwdev(void *udkdev);

void hiudk_update_sdk_state(enum hiudk_sdk_state sdk_state);

#if defined(HIUDK_ULD) || defined(HIUDK_SDK_ADPT)
#define hinic3_hwdev hiudk_dev
#endif

#endif
#endif
